/**
 * 
 */
package org.paybiz.core.payplatform.yeePay.service;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.paybiz.constant.ErrorConstant;
import org.paybiz.core.payplatform.bill99.entity.ResultVO;
import org.paybiz.core.payplatform.yeePay.bean.RechargeCardPay;
import org.paybiz.core.payplatform.yeePay.constant.RechargeCardConstant;
import org.paybiz.core.payplatform.yeePay.constant.RechargeCardConstant.RechargeCardCommitResult;
import org.paybiz.core.payplatform.yeePay.constant.YeepayConstant;
import org.paybiz.core.payplatform.yeePay.util.DigestUtil;
import org.paybiz.core.payplatform.yeePay.util.HttpUtils;
import org.paybiz.util.DynamicConfig;

/**
 * 充值卡支付
 * 
 * @author nassir wen
 * @data 2012-3-30 下午04:11:10
 * @version V2.5
 * @Company: MSD.
 * @Copyright Copyright (c) 2012
 */
public class RechargeCardPayHandler {

    private final static Log logger = LogFactory
            .getLog(RechargeCardPayHandler.class);

    private static String rechargeCardPayUrl = "https://www.yeepay.com/app-merchant-proxy/command.action";

    private static String rechargeCardPayCallbackUrl = "";

    // 商户编号
    private static String p1_MerId = "";

    // 商户密钥
    private static String keyValue = "";

    static {
        p1_MerId = DynamicConfig.getInstance().getValue(YeepayConstant.P1_MERID);
        keyValue = DynamicConfig.getInstance().getValue(YeepayConstant.KEYVALUE);
        rechargeCardPayUrl = DynamicConfig.getInstance().getValue(
                YeepayConstant.RECHARGE_CARD_PAY_URL);
        rechargeCardPayCallbackUrl = DynamicConfig.getInstance().getValue(
                YeepayConstant.RECHARGE_CARD_PAY_CALLBACK_URL);
    }

    public static ResultVO rechargeCardPay(RechargeCardPay rechargeCardPay) {
        String hmac = getHmac(rechargeCardPay);
        Map<String, String> reqParams = new HashMap<String, String>();
        reqParams.put("p0_Cmd", "ChargeCardDirect");
        reqParams.put("p1_MerId", p1_MerId);
        reqParams.put("p2_Order", rechargeCardPay.getOrderId());
        reqParams.put("p3_Amt", rechargeCardPay.getPayAmount() + "");
        reqParams.put("p4_verifyAmt", rechargeCardPay.getVerifyAmount());
        reqParams.put("p5_Pid", rechargeCardPay.getProductName());
        reqParams.put("p6_Pcat", "");
        reqParams.put("p7_Pdesc", "");
        reqParams.put("p8_Url", rechargeCardPayCallbackUrl);
        reqParams.put("pa_MP", "");
        reqParams.put("pa7_cardAmt", rechargeCardPay.getCardAmount() + "");
        reqParams.put("pa8_cardNo", rechargeCardPay.getCardNo());
        reqParams.put("pa9_cardPwd", rechargeCardPay.getCardPasswd());
        reqParams.put(
                "pd_FrpId",
                RechargeCardConstant.getRechargeCardTypeEnum(
                        rechargeCardPay.getCardType()).name());
        reqParams.put("pr_NeedResponse", "1");
        reqParams.put("pz_userId", "");
        reqParams.put("pz1_userRegTime", "");
        reqParams.put("hmac", hmac);
        ResultVO result = new ResultVO();
        try {
            Map<String, String> requestResult = HttpUtils.httpsPost(
                    rechargeCardPayUrl, reqParams);
            result = verifyResult(requestResult);
        } catch (IOException e) {
            result.setResultCode(ErrorConstant.SYSTEM_BUYS_ID);
            result.setErrMsg(ErrorConstant.SYSTEM_BUYS_VALUE);
        }
        return result;
    }

    private static String getHmac(RechargeCardPay rechargeCardPay) {
        return DigestUtil.getHmac(
                new String[] {
                        "ChargeCardDirect",
                        p1_MerId,
                        rechargeCardPay.getOrderId(),
                        rechargeCardPay.getPayAmount() + "",
                        rechargeCardPay.getVerifyAmount(),
                        rechargeCardPay.getProductName(),
                        "",
                        "",
                        rechargeCardPayCallbackUrl,
                        "",
                        rechargeCardPay.getCardAmount() + "",
                        rechargeCardPay.getCardNo(),
                        rechargeCardPay.getCardPasswd(),
                        RechargeCardConstant.getRechargeCardTypeEnum(
                                rechargeCardPay.getCardType()).name(), "1",// 需要应答
                        "", "" }, keyValue);
    }

    private static boolean getRequestHmac(Map<String, String> requestResult) {
        String[] waitForHmacStr = new String[] { requestResult.get("r0_Cmd"),
                requestResult.get("r1_Code"), requestResult.get("r6_Order"),
                requestResult.get("rq_ReturnMsg") };
        String localHmac = DigestUtil.getHmac(waitForHmacStr, keyValue);
        String hmac = requestResult.get("hmac");
        return StringUtils.equals(localHmac, hmac);
    }

    private static ResultVO verifyResult(Map<String, String> requestResult) {
        ResultVO result = new ResultVO();
        if (getRequestHmac(requestResult)) {
            String code = requestResult.get("r1_Code");
            if (StringUtils.isNotEmpty(code)) {
                if (Integer.parseInt(code) == RechargeCardCommitResult.COMMIT_SUCCESS
                        .key()) {
                    result.setResultCode(RechargeCardCommitResult.COMMIT_SUCCESS
                            .key() + "");
                } else {
                    logger.error("第三方充值卡支付失败 ");
                    result.setResultCode(code);
                    result.setErrMsg("第三方充值卡支付失败");
                }
            }else {
                result.setResultCode(ErrorConstant.RECHARGE_CARD_THIRD_PARTNER_SERVICE_ERROR);
                result.setErrMsg(ErrorConstant.RECHARGE_CARD_THIRD_PARTNER_SERVICE_ERROR_VALUE);
                logger.error(ErrorConstant.RECHARGE_CARD_THIRD_PARTNER_SERVICE_ERROR_VALUE);
            }
        } else {
            result.setResultCode(ErrorConstant.SIGN_FAIL_ID);
            result.setErrMsg("第三方返回数据" + ErrorConstant.SIGN_FAIL_VALUE);
            logger.error("第三方返回数据" + ErrorConstant.SIGN_FAIL_VALUE);
        }
        return result;
    }
}
